﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.DataModel;
using YArchitech.LIB;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class LevelMark : IExternalCommand
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			if (commandData == null)
			{
				throw new NotImplementedException();
			}
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			Document document = activeUIDocument.Document;
			Selection selection = activeUIDocument.Selection;
			if (!YJKRevitTools.ViewCheck(activeUIDocument, new List<ViewType>
			{
				(ViewType)1,
				(ViewType)2,
				(ViewType)4
			}))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			Autodesk.Revit.DB.View activeView = activeUIDocument.ActiveView;
			if (activeView is View3D && !(activeView as View3D).IsLocked)
			{
				YJKMessageBox.Warning("该三维视图无法标注，请锁定视角后再进行此操作！");
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			RevitVersionFuncs.ClearSelection(selection);
			UserSetting userSetting = new UserSetting();
			if (LevelMark.hWndRevit == null)
			{
				LevelMark.hWndRevit = new YJKWindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			int display = 0;
			string value = userSetting.GetValue("LevelMark", "DisplyElevations");
			if (value != null)
			{
				display = Convert.ToInt32(value);
			}
			LeveMarkForm leveMarkForm = new LeveMarkForm(document, display);
			Result result;
			try
			{
				leveMarkForm.Show(LevelMark.hWndRevit);
				for (;;)
				{
					transaction = new Transaction(document, "标高标注");
					transaction.Start();
					int wMsg = 7;
					LevelMark.SendMessage(LevelMark.hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
					ISelectionFilter selectionFilter = new HoriDuctAndPipeFilter();
					Reference reference;
					if (document.ActiveView is View3D && (int)document.ActiveView.DetailLevel == 3)
					{
						reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)3, "请选择要标注的水管或风管");
					}
					else
					{
						reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "请选择要标注的水管或风管");
					}
					Element element = document.GetElement(reference);
					XYZ xyz = selection.PickPoint("请选择引线拐点");
					XYZ xyz2 = selection.PickPoint("请选择标注位置点");
					SpotDimension spotDimension = null;
					if (element.Location is LocationPoint)
					{
						spotDimension = document.Create.NewSpotElevation(document.ActiveView, reference, (element.Location as LocationPoint).Point, xyz, xyz2, (element.Location as LocationPoint).Point, true);
						if (xyz.Y < (element.Location as LocationPoint).Point.Y)
						{
							spotDimension.ChangeTypeId(new ElementId(this.GetSpotDimTypeId(spotDimension)));
						}
					}
					else if (element.Location is LocationCurve)
					{
						spotDimension = document.Create.NewSpotElevation(document.ActiveView, reference, reference.GlobalPoint, xyz, xyz2, reference.GlobalPoint, true);
						if (xyz.Y < reference.GlobalPoint.Y)
						{
							spotDimension.ChangeTypeId(new ElementId(this.GetSpotDimTypeId(spotDimension)));
						}
					}
					if (!(document.ActiveView is View3D))
					{
						spotDimension.GetParameter(BuiltInParameter.SPOT_ELEV_DISPLAY_ELEVATIONS).Set(leveMarkForm.GetDisplayElevation());
					}
					transaction.Commit();
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				userSetting.WriteValue("LevelMark", "DisplyElevations", leveMarkForm.GetDisplayElevation().ToString());
				leveMarkForm.Close();
				if (transaction != null && 1 == (int)transaction.GetStatus())
				{
					transaction.RollBack();
				}
			}
			return result;
		}

		private int GetSpotDimTypeId(SpotDimension spot)
		{
			int num = 0;
			string text = spot.SpotDimensionType.Name + "下";
			try
			{
				foreach (Element element in new FilteredElementCollector(spot.Document).OfClass(typeof(SpotDimensionType)))
				{
					if (element.Name == text)
					{
						num = element.Id.IntegerValue;
					}
				}
				if (num == 0)
				{
					SpotDimensionType spotDimensionType = spot.SpotDimensionType.Duplicate(text) as SpotDimensionType;
					spotDimensionType.GetParameter("文字位置").Set(1);
					num = spotDimensionType.Id.IntegerValue;
				}
			}
			catch (Exception ex)
			{
				YJKMessageBox.Error(ex.Message);
				throw;
			}
			return num;
		}

		public static YJKWindowHandle hWndRevit;
	}
}
